#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <chrono>

// TLV消息结构
struct Message
{
    int tag;
    int length;
    std::string value;
};

// 解析TLV响应
Message parseTLVResponse(const std::string &data)
{
    Message msg;

    if (data.size() >= sizeof(int) * 2)
    {
        // 解析tag
        std::memcpy(&msg.tag, data.data(), sizeof(msg.tag));
        // 解析length
        std::memcpy(&msg.length, data.data() + sizeof(msg.tag), sizeof(msg.length));
        // 解析value
        if (data.size() >= sizeof(int) * 2 + msg.length)
        {
            msg.value = data.substr(sizeof(int) * 2, msg.length);
        }
    }

    return msg;
}

void send_keyword_request(const std::string &keyword)
{
    std::cout << "🔍 搜索关键词: '" << keyword << "'" << std::endl;

    // 创建socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cerr << "❌ 创建socket失败" << std::endl;
        return;
    }

    // 设置接收超时
    struct timeval timeout;
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    // 连接服务器
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8888);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);

    if (connect(sockfd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        std::cerr << "❌ 连接服务器失败" << std::endl;
        close(sockfd);
        return;
    }

    std::cout << "✅ 连接服务器成功" << std::endl;

    // 构建TLV请求数据：tag=1 (关键字推荐)
    int tag = 1;
    int length = keyword.size();

    std::string tlv_data;
    tlv_data.append(reinterpret_cast<const char *>(&tag), sizeof(tag));
    tlv_data.append(reinterpret_cast<const char *>(&length), sizeof(length));
    tlv_data.append(keyword);

    // 发送请求
    ssize_t sent = send(sockfd, tlv_data.c_str(), tlv_data.size(), 0);
    std::cout << "📤 发送请求: " << sent << " 字节" << std::endl;

    // 等待服务器处理
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    // 接收响应
    char buffer[4096];
    ssize_t received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);

    if (received > 0)
    {
        // 解析TLV响应
        Message response = parseTLVResponse(std::string(buffer, received));

        std::cout << "📋 服务器响应:" << std::endl;
        std::cout << "  Tag: " << response.tag << std::endl;
        std::cout << "  Length: " << response.length << std::endl;
        std::cout << "  Value: " << std::endl;
        std::cout << "========================================" << std::endl;
        std::cout << response.value << std::endl;
        std::cout << "========================================" << std::endl;
    }
    else if (received == 0)
    {
        std::cout << "⚠️  服务器关闭连接" << std::endl;
    }
    else
    {
        std::cout << "❌ 接收响应失败或超时" << std::endl;
    }

    close(sockfd);
    std::cout << "----------------------------------------" << std::endl;
}

void send_web_search_request(const std::string &query)
{
    std::cout << "🌐 网页搜索: '" << query << "'" << std::endl;

    // 创建socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cerr << "❌ 创建socket失败" << std::endl;
        return;
    }

    // 设置接收超时
    struct timeval timeout;
    timeout.tv_sec = 15; // 网页搜索可能需要更长时间
    timeout.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    // 连接服务器
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8888);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);

    if (connect(sockfd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        std::cerr << "❌ 连接服务器失败" << std::endl;
        close(sockfd);
        return;
    }

    std::cout << "✅ 连接服务器成功" << std::endl;

    // 构建TLV请求数据：tag=2 (网页搜索)
    int tag = 2;
    int length = query.size();

    std::string tlv_data;
    tlv_data.append(reinterpret_cast<const char *>(&tag), sizeof(tag));
    tlv_data.append(reinterpret_cast<const char *>(&length), sizeof(length));
    tlv_data.append(query);

    // 发送请求
    ssize_t sent = send(sockfd, tlv_data.c_str(), tlv_data.size(), 0);
    std::cout << "📤 发送请求: " << sent << " 字节" << std::endl;

    // 等待服务器处理
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    // 接收响应
    char buffer[8192]; // 网页搜索结果可能更大
    ssize_t received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);

    if (received > 0)
    {
        // 解析TLV响应
        Message response = parseTLVResponse(std::string(buffer, received));

        std::cout << "📋 网页搜索结果:" << std::endl;
        std::cout << "  Tag: " << response.tag << std::endl;
        std::cout << "  Length: " << response.length << std::endl;
        std::cout << "  Value: " << std::endl;
        std::cout << "========================================" << std::endl;
        std::cout << response.value << std::endl;
        std::cout << "========================================" << std::endl;
    }
    else if (received == 0)
    {
        std::cout << "⚠️  服务器关闭连接" << std::endl;
    }
    else
    {
        std::cout << "❌ 接收响应失败或超时" << std::endl;
    }

    close(sockfd);
    std::cout << "----------------------------------------" << std::endl;
}

int main()
{
    std::cout << "🚀 搜索引擎客户端" << std::endl;
    std::cout << "使用说明:" << std::endl;
    std::cout << "  直接输入关键词 - 关键字推荐" << std::endl;
    std::cout << "  w:搜索内容     - 网页搜索" << std::endl;
    std::cout << "  输入 'quit' 退出" << std::endl;
    std::cout << "========================================" << std::endl;

    while (true)
    {
        std::string input;
        std::cout << "请输入: ";
        std::getline(std::cin, input);

        if (input == "quit" || input == "exit")
        {
            break;
        }

        if (input.empty())
        {
            continue;
        }

        // 检查是否是网页搜索命令
        if (input.length() > 2 && input.substr(0, 2) == "w:")
        {
            std::string query = input.substr(2);
            if (!query.empty())
            {
                send_web_search_request(query);
            }
            else
            {
                std::cout << "❌ 网页搜索内容不能为空" << std::endl;
            }
        }
        else
        {
            // 默认作为关键字推荐
            send_keyword_request(input);
        }
    }

    std::cout << "再见！" << std::endl;
    return 0;
}